conf = require("../config")
if not conf.conform.enabled then return {} end

local formatter = {
  "stylua",       -- lua
  "verible",      -- verilog
  "ruff",         -- python
  "clang-format"  -- C/C++
}

local function format()
	local mode = vim.api.nvim_get_mode().mode

	if mode:match("[vV]") then
		local start_line = vim.fn.line("'<")
		local end_line = vim.fn.line("'>")
		require("conform").format({
			lsp_fallback = true,
			range = {
				start = { start_line, 0 },
				["end"] = { end_line, 0 },
			},
		})
	else
		require("conform").format({ lsp_fallback = true })
	end
end

vim.api.nvim_create_autocmd("User", {
  pattern = "LazyDone",
  group = vim.api.nvim_create_augroup('conform', {clear = true}),
  callback = function()
    local mr = require("mason-registry")
    local has_mr, mr = pcall(require, "mason-registry")
		if  has_mr then
			-- local mr = require("mason-registry")
      -- local has_mr, mr = pcall(require, "mason-registry")
			mr:on("package:install:success", function()
				vim.defer_fn(function()
					-- trigger FileType event to possibly load this newly installed LSP server
					require("lazy.core.handler.event").trigger({
							event = "FileType",
							buf = vim.api.nvim_get_current_buf(),
						})
				end, 100)
			end)

			mr.refresh(function()
				for _, tool in ipairs(formatter) do
					local p = mr.get_package(tool)
					if not p:is_installed() then
						p:install()
					end
				end
			end)
		end
  end
})

return {
	"stevearc/conform.nvim",
	dependencies = { "mason.nvim" },
	lazy = true,
	cmd = "ConformInfo",
	keys = {
		{
			"<space>cF",
			function()
				require("conform").format({ formatters = { "injected" }, timeout_ms = 3000 })
			end,
			mode = { "n", "v" },
			desc = "Format Injected Langs",
		},
		{
			"<space>cf",
			function()
				format()
			end,
			mode = { "n", "v" },
			desc = "Format Selected Langs",
		},
	},
  opts_extend = { "ensure_installed" },
	opts = {
    ensure_installed = formatter,
		-- Map of filetype to formatters
		formatters_by_ft = {
			lua = { "stylua" },
			-- You can also customize some of the format options for the filetype
			rust = { "rustfmt", lsp_format = "fallback" },
			-- You can use a function here to determine the formatters dynamically
			python = function(bufnr)
				if require("conform").get_formatter_info("ruff_format", bufnr).available then
					return { "ruff_format" }
				else
					return { "isort", "black" }
				end
			end,
      verilog = { "verible", lsp_format = "fallback" },
      systemverilog = { "verible", lsp_format = "fallback" },
      c = { "clang-format", lsp_format = "fallback" },
      cpp = { "clang-format", lsp_format = "fallback" },
			-- Use the "*" filetype to run formatters on all filetypes.
			["*"] = { "codespell" },
			-- Use the "_" filetype to run formatters on filetypes that don't
			-- have other formatters configured.
			["_"] = { "trim_whitespace" },
		},
		-- Set this to change the default values when calling conform.format()
		-- This will also affect the default values for format_on_save/format_after_save
		default_format_opts = {
			lsp_format = "fallback",
		},
		format_on_save = nil,
		format_after_save = nil,
		-- Set the log level. Use `:ConformInfo` to see the location of the log file.
		log_level = vim.log.levels.ERROR,
		-- Conform will notify you when a formatter errors
		notify_on_error = true,
		-- Conform will notify you when no formatters are available for the buffer
		notify_no_formatters = true,
		-- Custom formatters and overrides for built-in formatters
		formatters = {},
	},
}
